package com.tanhua.dubbo.api;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.db.Visitor;
import com.tanhua.domain.mongo.Friend;
import com.tanhua.domain.mongo.RecommendUser;
import com.tanhua.domain.mongo.UserLike;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.dubbo.mapper.UserInfoMapper;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class UserInfoImpl implements UserInfoApi {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private AnnouncementApi announcementApi;

    @Override
    public void add(UserInfo userInfo) {
        userInfoMapper.insert(userInfo);
    }

    @Override
    public void update(UserInfo userInfo) {
        userInfoMapper.updateById(userInfo);
    }

    @Override
    public UserInfo findUserById(Long userId) {
        return userInfoMapper.selectById(userId);
    }

    @Override
    public List<UserInfo> findByBatchIds(List<Long> ids) {
        return userInfoMapper.selectBatchIds(ids);
    }

    @Override
    public Long findLoveAndFan(Long longInUserId) {
        Query query = new Query(Criteria.where("userId").is(longInUserId));
        long count = mongoTemplate.count(query, Friend.class);
        return count;
    }

    @Override
    public Long findLove(Long longInUserId) {
        Query query = new Query(Criteria.where("userId").is(longInUserId));
        long count = mongoTemplate.count(query, UserLike.class);
        return count;
    }

    @Override
    public Long findFan(Long longInUserId) {
        Query query = new Query(Criteria.where("likeUserId").is(longInUserId));
        long count = mongoTemplate.count(query, UserLike.class);
        return count;
    }

    @Override
    public PageResult findEachAttention(Long longInUserId, Long page, Long pagesize) {
        Query query = new Query(Criteria.where("userId").is(longInUserId));
        long count = mongoTemplate.count(query, Friend.class);
        List<RecommendUser> recommendUsers = new ArrayList<>();
        if (count > 0) {
            query.skip((page - 1) * pagesize).limit(pagesize.intValue());
            query.with(Sort.by(Sort.Order.desc("dreated")));
            List<Friend> friendList = mongoTemplate.find(query, Friend.class);
            if (!CollectionUtils.isEmpty(friendList)) {
                List<Long> friendIdList = friendList.stream().map(Friend::getFriendId).collect(Collectors.toList());
                Query queryFriend = new Query(Criteria.where("userId").in(friendIdList).and("toUserId").is(longInUserId));
                recommendUsers = mongoTemplate.find(queryFriend, RecommendUser.class);
            }
        }
        return PageResult.pageResult(page, pagesize, recommendUsers, count);
    }

    @Override
    public PageResult findPggeLove(Long longInUserId, Long page, Long pagesize) {
        Query query = new Query(Criteria.where("userId").is(longInUserId));
        long count = mongoTemplate.count(query, UserLike.class);
        List<RecommendUser> recommendUsers = new ArrayList<>();
        if (count > 0) {
            query.skip((page - 1) * pagesize).limit(pagesize.intValue());
            query.with(Sort.by(Sort.Order.desc("created")));
            List<UserLike> userLikes = mongoTemplate.find(query, UserLike.class);
            if (!CollectionUtils.isEmpty(userLikes)) {
                List<Long> userLikeIds = userLikes.stream().map(UserLike::getLikeUserId).collect(Collectors.toList());
                Query queryUserLikes = new Query(Criteria.where("toUserId").is(longInUserId).and("userId").in(userLikeIds));
                recommendUsers = mongoTemplate.find(queryUserLikes, RecommendUser.class);
            }
        }
        return PageResult.pageResult(page, pagesize, recommendUsers, count);
    }

    @Override
    public PageResult findPageFans(Long longInUserId, Long page, Long pagesize) {
        Query query = new Query(Criteria.where("likeUserId").is(longInUserId));
        long count = mongoTemplate.count(query, UserLike.class);
        List<RecommendUser> recommendUsers = new ArrayList<>();
        if (count > 0) {
            query.skip((page - 1) * pagesize).limit(pagesize.intValue());
            query.with(Sort.by(Sort.Order.desc("created")));
            List<UserLike> userLikes = mongoTemplate.find(query, UserLike.class);
            if (!CollectionUtils.isEmpty(userLikes)) {
                List<Long> userLikeIds = userLikes.stream().map(UserLike::getUserId).collect(Collectors.toList());
                Query queryUserLikes = new Query(Criteria.where("toUserId").is(longInUserId).and("userId").in(userLikeIds));
                recommendUsers = mongoTemplate.find(queryUserLikes, RecommendUser.class);
            }
        }
        return PageResult.pageResult(page, pagesize, recommendUsers, count);
    }

    @Override
    public PageResult findPageLook(Long longInUserId, Long page, Long pagesize) {
        Query query = new Query(Criteria.where("userId").is(longInUserId));
        long count = mongoTemplate.count(query, Visitor.class);
        List<RecommendUser> recommendUsers = new ArrayList<>();
        if (count > 0) {
            query.with(Sort.by(Sort.Order.desc("date")));
            query.skip((page - 1) * pagesize).limit(pagesize.intValue());
            List<Visitor> visitors = mongoTemplate.find(query, Visitor.class);
            if (!CollectionUtils.isEmpty(visitors)) {
                List<Long> visitorIds = visitors.stream().map(Visitor::getVisitorUserId).collect(Collectors.toList());
                Query queryVisitors = new Query(Criteria.where("toUserId").is(longInUserId).and("userId").in(visitorIds));
                List<RecommendUser>   recommendUser1 = mongoTemplate.find(queryVisitors, RecommendUser.class);
                Map<Long, RecommendUser> recommentMap = recommendUser1.stream().collect(Collectors.toMap(RecommendUser::getUserId, u -> u));
                for (Visitor visitor : visitors) {
                    RecommendUser recommendUser = recommentMap.get(visitor.getVisitorUserId());
                    recommendUsers.add(recommendUser);
                }
            }
        }
        return PageResult.pageResult(page, pagesize, recommendUsers, count);
    }

    @Override
    public Boolean likeFences(Long userId, Long likeId) {
        Query query = new Query(Criteria.where("userId").is(likeId).and("likeUserId").is(userId));
        if (mongoTemplate.exists(query,UserLike.class)){
            mongoTemplate.remove(query,UserLike.class);
            announcementApi.addFriend(userId,likeId.intValue());
            return true;
        }
        UserLike userLike = new UserLike();
        userLike.setCreated(System.currentTimeMillis());
        userLike.setUserId(userId);
        userLike.setLikeUserId(likeId);
        mongoTemplate.insert(userLike);
        return false;
    }

    @Override
    public List<UserInfo> findAlluser() {
        QueryWrapper<UserInfo> UserInfoQueryWrapper = new QueryWrapper<>();
        return userInfoMapper.selectList(UserInfoQueryWrapper);
    }
}
